package com.cskaoyan.aspecj;


import com.cskaoyan.bean.MarketAdmin;
import com.cskaoyan.bean.MarketLog;
import com.cskaoyan.bean.common.BaseRespVo;
import com.cskaoyan.mapper.MarketLogMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * zjq
 * 能跑就行。。。
 */
@Component
@Aspect
public class LogAspect {

    @Autowired
    MarketLogMapper marketLogMapper;

    @Pointcut("execution(* *delete*(..))")
    private void deleteMethod() {
    }

    @Pointcut("execution(* *update*(..))")
    private void updateMethod() {
    }

    @Pointcut("execution(* *create*(..))")
    private void createMethod() {
    }

    @Pointcut("execution(* *login*(..))")
    private void loginMethod() {
    }

    @Pointcut("execution(* *logout*(..))")
    private void logoutMethod() {
    }

    @Pointcut("execution(* com.cskaoyan.controller.admin.*.*(..))")
    private void controller() {
    }

    /**
     * zjq
     * 增 删 改 方法
     */
    //    @Pointcut("(deleteMethod()||updateMethod()||createMethod()||loginMethod()||logoutMethod())&&controller()")
    @Pointcut("controller()&&(deleteMethod()||updateMethod()||createMethod())")
    private void anyAdminMethod() {
    }






    /**
     * zjq
     * 记录增 删 改 方法的advice
     * @param joinPoint
     * @return
     */
    @Around("com.cskaoyan.aspecj.LogAspect.anyAdminMethod()")
//    @Around("com.cskaoyan.aspect.LogAspect.storageControl()")
    public Object log1(ProceedingJoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        MarketLog marketLog = new MarketLog();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //获取请求信息
        marketLog.setAdmin((String) request.getSession().getAttribute("admin"));
        marketLog.setIp(request.getRemoteAddr());
        marketLog.setAddTime(new Date());
        marketLog.setUpdateTime(new Date());
        marketLog.setType(1);
        Subject subject = SecurityUtils.getSubject();
        //防止重启服务器让页面出错
        MarketAdmin primaryPrincipal = new MarketAdmin();
        if(subject.isAuthenticated()){
            primaryPrincipal= (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();

        }
        marketLog.setAdmin(primaryPrincipal.getUsername());
        marketLog.setStatus(subject.isAuthenticated());
        // todo 操作类别(安全操作还是订单操作)
        String requestURI = request.getRequestURI();

        String option = parseRequestOptions(requestURI);
        String target = parseRequestTarget(requestURI);
        marketLog.setAction(option + target);
        marketLog.setDeleted(false);
        Object proceed = new Object();
        try {
            proceed = joinPoint.proceed(args);
            BaseRespVo baseRespVo = (BaseRespVo)proceed;
            int errno = baseRespVo.getErrno();
            if(errno!=0){
                marketLog.setResult("操作失败");
                marketLog.setComment(baseRespVo.getErrmsg());
                marketLog.setStatus(false);
            }else{
                marketLog.setResult("操作成功");
                marketLog.setStatus(true);
                marketLog.setComment(baseRespVo.getErrmsg());
            }
        } catch (Throwable e) {
            marketLog.setResult("操作失败");
            marketLog.setStatus(false);
            marketLog.setComment("代码异常");
        } finally {
            marketLogMapper.insertSelective(marketLog);

        }
        return proceed;
    }

    /**
     * 张家齐
     * 记录登录的advice
     * @return
     */
   @Around("loginMethod()&&controller()")
   private Object log2(ProceedingJoinPoint joinPoint){
       MarketLog marketLog = new MarketLog();
       ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
       HttpServletRequest request = attributes.getRequest();
       //获取请求信息
       marketLog.setIp(request.getRemoteAddr());
       marketLog.setAddTime(new Date());
       marketLog.setUpdateTime(new Date());
       marketLog.setAction("登录");
       marketLog.setType(1);
       Object[] args = joinPoint.getArgs();
       Object proceed = new Object();
       try{
           proceed= joinPoint.proceed(args);
           BaseRespVo baseRespVo =(BaseRespVo) proceed;
           if(baseRespVo.getErrno()==0){
               marketLog.setResult("登录成功");
               marketLog.setStatus(true);
               Subject subject = SecurityUtils.getSubject();
               MarketAdmin primaryPrincipal = (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();
               marketLog.setAdmin(primaryPrincipal.getUsername());
           }
           else {
               marketLog.setResult("登录失败");
               marketLog.setStatus(false);
               marketLog.setComment(baseRespVo.getErrmsg());
           }
       }catch (Throwable e) {
           marketLog.setStatus(false);
           marketLog.setResult("登录失败");
           marketLog.setResult("代码错误");
       }finally {

           marketLogMapper.insertSelective(marketLog);
       }
       return proceed;
   }

    /**
     * 张家齐
     * 记录登出的advice
     * @return
     */
    @Around("logoutMethod()&&controller()")
    private Object log3(ProceedingJoinPoint joinPoint){
        MarketLog marketLog = new MarketLog();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //获取请求信息
        marketLog.setIp(request.getRemoteAddr());
        marketLog.setAddTime(new Date());
        marketLog.setUpdateTime(new Date());
        marketLog.setAction("登出");
        marketLog.setType(1);
        Object[] args = joinPoint.getArgs();
        Subject subject = SecurityUtils.getSubject();
        //防止重启服务器让页面出错
        MarketAdmin primaryPrincipal = new MarketAdmin();
        if(subject.isAuthenticated()){
            primaryPrincipal= (MarketAdmin) subject.getPrincipals().getPrimaryPrincipal();
        }
        Object proceed = new Object();
        try{
            proceed= joinPoint.proceed(args);
            BaseRespVo baseRespVo =(BaseRespVo) proceed;
            if(baseRespVo.getErrno()==0){
                marketLog.setStatus(true);
                marketLog.setResult("登出成功");
                marketLog.setAdmin(primaryPrincipal.getUsername());
            }
            else {
                marketLog.setStatus(false);
                marketLog.setResult("登出失败");
                marketLog.setComment(baseRespVo.getErrmsg());
                marketLog.setAdmin(primaryPrincipal.getUsername());
            }
        }catch (Throwable e) {
            marketLog.setStatus(false);
            marketLog.setResult("登出失败");
            marketLog.setComment("代码错误");
        }finally {
            marketLogMapper.insertSelective(marketLog);
        }
        return proceed;
    }





    private String parseRequestTarget(String requestURI) {
        if (requestURI.contains("admin/admin")) {
            return "管理员";
        }
        if (requestURI.contains("admin/brand")) {
            return "品牌制造商";
        }
        if (requestURI.contains("admin/category")) {
            return "商品类目";
        }
        if (requestURI.contains("admin/order")) {
            return "订单";
        }
        if (requestURI.contains("admin/issue")) {
            return "通用问题";
        }
        if (requestURI.contains("admin/admin")) {
            return "关键词";
        }
        if (requestURI.contains("admin/goods")) {
            return "商品管理";
        }
        if (requestURI.contains("admin/comment")) {
            return "评论";
        }
        if (requestURI.contains("admin/storage")) {
            return "对象（图片）";
        }
        if (requestURI.contains("admin/ad")) {
            return "广告";
        }
        if (requestURI.contains("admin/coupon")) {
            return "优惠卷";
        }
        if (requestURI.contains("admin/topic")) {
            return "专题";
        }
        if (requestURI.contains("admin/admin")) {
            return "管理员";
        }
        if (requestURI.contains("admin/role")) {
            return "角色";
        }
        if (requestURI.contains("admin/config")) {
            return "配置";
        }
        return "";
    }


    private String parseRequestOptions(String requestURI) {
        if (requestURI.contains("delete")) {
            return "删除";
        }
        if (requestURI.contains("login")) {
            return "登录";
        }
        if (requestURI.contains("logout")) {
            return "退出登录";
        }
        if (requestURI.contains("update")) {
            return "更新";
        }
        if (requestURI.contains("create")) {
            return "新增";
        }
        return requestURI;
    }

//    //获取请求的相关信息
//    private Map<String, Object> getRequestParams(JoinPoint joinPoint) throws UnsupportedEncodingException {
//        Map<String, Object> requestParams = new HashMap<>();
//        //获取请求信息
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        HttpServletRequest request = attributes.getRequest();
//        requestParams.put("uri", request.getRequestURI());
//        // 获取请求头信息,需要注意的是，请求头中的key都会转成小写
//        Enumeration<String> enumeration = request.getHeaderNames();
//        JSONObject headers = new JSONObject();
//        while (enumeration.hasMoreElements()) {
//            String name = enumeration.nextElement();
//            String value = request.getHeader(name);
//            headers.put(name, value);
//        }
//        requestParams.put("headers", headers);
//        //获取请求的方法
//        String method = request.getMethod();
//        requestParams.put("method", method);
//        List<String> params = new ArrayList<>();
//        if (HttpMethod.GET.toString().equals(method)) {// get请求
//            String queryString = request.getQueryString();
//            if (StringUtils.isNotBlank(queryString)) {
//                params.add(0, URLDecoder.decode(queryString, "UTF-8"));
//            }
//        } else {//其他请求
//            Object[] paramsArray = joinPoint.getArgs();
//            if (paramsArray != null && paramsArray.length > 0) {
//                for (int i = 0; i < paramsArray.length; i++) {
//                    if (paramsArray[i] instanceof Serializable) {
//                        params.add(paramsArray[i].toString());
//                    } else {
//                        try {
//                            //使用json系列化 反射等等方法 反系列化会影响请求性能建议重写toString方法实现系列化接口
//                            String param = objectMapper.writeValueAsString(paramsArray[i]);
//                            if (StringUtils.isNotBlank(param))
//                                params.add(param);
//                        } catch (JsonProcessingException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//            }
//        }
//
//        return requestParams;
//    }
}
